home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / filutil / msbin.zip / MSBIN.C < prev    next >
Text File  |  1993-04-01  |  7KB  |  250 lines

  1. //
  2. // The following are implementations of Microsoft RTL functions not
  3. // include in the Borland RTL.
  4. //
  5. // Functions:
  6. //     _fmsbintoieee()
  7. //     _fieeetomsbin()
  8. //     _dmsbintoieee()
  9. //     _dieeetomsbin()
  10. //
  11. // These functions convert back and forth from Microsoft Binary Format
  12. // to IEEE floating point format.
  13. //
  14. // As with the Microsoft RTL functions,
  15. //
  16. // The argument srcX points to the value to be converted and the
  17. // result is stored at the location given at destX.
  18. //
  19. // These routines do not handle IEE NAN's and infinities.  IEEE
  20. // denormals are treated as 0's.
  21. //
  22. // Return:
  23. //
  24. // These functions return 0 if the conversion is successful and 1
  25. // if the conversion causes an overflow.
  26. //
  27. //
  28. //
  29. // Examples of the use of these functions can be found online as
  30. // MSBIN.ZIP.
  31. //
  32. //--------------------------------------------------------------------
  33.  
  34.  
  35.  
  36.  
  37. #include <string.h>        /* for strncpy  */
  38.  
  39. int _fmsbintoieee(float *src4, float *dest4)
  40.    {
  41.    unsigned char *msbin = (unsigned char *)src4;
  42.    unsigned char *ieee = (unsigned char *)dest4;
  43.    unsigned char sign = 0x00;
  44.    unsigned char ieee_exp = 0x00;
  45.    int i;
  46.  
  47.    /* MS Binary Format                         */
  48.    /* byte order =>    m3 | m2 | m1 | exponent */
  49.    /* m1 is most significant byte => sbbb|bbbb */
  50.    /* m3 is the least significant byte         */
  51.    /*      m = mantissa byte                   */
  52.    /*      s = sign bit                        */
  53.    /*      b = bit                             */
  54.  
  55.    sign = msbin[2] & 0x80;      /* 1000|0000b  */
  56.                                                
  57.    /* IEEE Single Precision Float Format       */
  58.    /*    m3        m2        m1     exponent   */
  59.    /* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee  */
  60.    /*          s = sign bit                    */
  61.    /*          e = exponent bit                */
  62.    /*          m = mantissa bit                */
  63.  
  64.    for (i=0; i<4; i++) ieee[i] = 0;
  65.  
  66.    /* any msbin w/ exponent of zero = zero */
  67.    if (msbin[3] == 0) return 0;
  68.    
  69.    ieee[3] |= sign;
  70.  
  71.    /* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places   */
  72.    /* the decimal point before the assumed bit, while          */
  73.    /* IEEE places the decimal point after the assumed bit.     */
  74.  
  75.    ieee_exp = msbin[3] - 2;    /* actually, msbin[3]-1-128+127 */
  76.  
  77.    /* the first 7 bits of the exponent in ieee[3] */
  78.    ieee[3] |= ieee_exp >> 1;   
  79.  
  80.    /* the one remaining bit in first bin of ieee[2] */
  81.    ieee[2] |= ieee_exp << 7;   
  82.  
  83.    /* 0111|1111b : mask out the msbin sign bit */
  84.    ieee[2] |= msbin[2] & 0x7f;
  85.  
  86.    ieee[1] = msbin[1];
  87.    ieee[0] = msbin[0];
  88.  
  89.    return 0;
  90.    }
  91.  
  92.  
  93. int _fieeetomsbin(float *src4, float *dest4)
  94.    {
  95.    unsigned char *ieee = (unsigned char *)src4;
  96.    unsigned char *msbin = (unsigned char *)dest4;
  97.    unsigned char sign = 0x00;
  98.    unsigned char msbin_exp = 0x00;
  99.    int i;
  100.  
  101.    /* See _fmsbintoieee() for details of formats   */
  102.    sign = ieee[3] & 0x80;
  103.    msbin_exp |= ieee[3] << 1;
  104.    msbin_exp |= ieee[2] >> 7;
  105.  
  106.    /* An ieee exponent of 0xfe overflows in MBF    */
  107.    if (msbin_exp == 0xfe) return 1;
  108.  
  109.    msbin_exp += 2;     /* actually, -127 + 128 + 1 */
  110.  
  111.    for (i=0; i<4; i++) msbin[i] = 0;
  112.  
  113.    msbin[3] = msbin_exp;
  114.  
  115.    msbin[2] |= sign;
  116.    msbin[2] |= ieee[2] & 0x7f;
  117.    msbin[1] = ieee[1];
  118.    msbin[0] = ieee[0];
  119.  
  120.    return 0;
  121.    }
  122.  
  123.  
  124.  
  125. int _dmsbintoieee(double *src8, double *dest8)
  126.    {
  127.    unsigned char msbin[8];
  128.    unsigned char *ieee = (unsigned char *)dest8;
  129.    unsigned char sign = 0x00;
  130.    unsigned int ieee_exp = 0x0000;
  131.    int i;
  132.  
  133.    /* A manipulatable copy of the msbin number     */
  134.    strncpy((char *)msbin,(char *)src8,8);
  135.  
  136.    /* MS Binary Format                                             */
  137.    /* byte order =>    m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponent */
  138.    /* m1 is most significant byte => smmm|mmmm                     */
  139.    /* m7 is the least significant byte                             */
  140.    /*      m = mantissa byte                                       */
  141.    /*      s = sign bit                                            */
  142.    /*      b = bit                                                 */
  143.  
  144.    sign = msbin[6] & 0x80;      /* 1000|0000b  */
  145.  
  146.    
  147.    /* IEEE Single Precision Float Format                           */
  148.    /*  byte 8    byte 7    byte 6    byte 5    byte 4    and so on */
  149.    /* seee|eeee eeee|mmmm mmmm|mmmm mmmm|mmmm mmmm|mmmm ...        */
  150.    /*          s = sign bit                                        */
  151.    /*          e = exponent bit                                    */
  152.    /*          m = mantissa bit                                    */
  153.  
  154.    for (i=0; i<8; i++) ieee[i] = 0;
  155.  
  156.    /* any msbin w/ exponent of zero = zero */
  157.    if (msbin[7] == 0) return 0;
  158.  
  159.  
  160.    ieee[7] |= sign;
  161.  
  162.    /* MBF is bias 128 and IEEE is bias 1023. ALSO, MBF places  */
  163.    /* the decimal point before the assumed bit, while          */
  164.    /* IEEE places the decimal point after the assumed bit.     */
  165.    
  166.    ieee_exp = msbin[7] - 128 - 1 + 1023;
  167.  
  168.    /* First 4 bits of the msbin exponent   */
  169.    /* go into the last 4 bits of ieee[7]   */
  170.    ieee[7] |= ieee_exp >> 4;
  171.  
  172.    /* The last 4 bits of msbin exponent    */
  173.    /* go into the first 4 bits of ieee[6]  */
  174.    ieee[6] |= ieee_exp << 4;
  175.  
  176.    /* The msbin mantissa must be shifted to the right 1 bit.   */
  177.    /* Remember that the msbin number has its bytes reversed.   */
  178.    for (i=6; i>0; i--)
  179.        {
  180.        msbin[i] <<= 1;
  181.        msbin[i] |= msbin[i-1] >> 7;
  182.        }
  183.    msbin[0] <<= 1;
  184.  
  185.    /* Now the mantissa is put into the ieee array starting in  */
  186.    /* the middle of the second to last byte.                   */
  187.  
  188.    for (i=6; i>0; i--)
  189.        {
  190.        ieee[i] |= msbin[i] >> 4;
  191.        ieee[i-1] |= msbin[i] << 4;
  192.        }
  193.    ieee[0] |= msbin[0] >> 4;
  194.  
  195.    /* IEEE has a half byte less for its mantissa.  If the msbin    */
  196.    /* number has anything in this last half byte, then there is an */
  197.    /* overflow.                                                    */
  198.    if (msbin[0] & 0x0f) 
  199.        return 1;
  200.    else
  201.        return 0;
  202.    }
  203.  
  204. int _dieeetomsbin(double *src8, double *dest8)
  205.    {
  206.    unsigned char ieee[8];
  207.    unsigned char *msbin = (unsigned char *)dest8;
  208.    unsigned char sign = 0x00;
  209.    unsigned char any_on = 0x00;
  210.    unsigned int msbin_exp = 0x0000;
  211.    int i;
  212.  
  213.    /* Make a clobberable copy of the source number */ 
  214.    strncpy((char *)ieee,(char *)src8,8);
  215.  
  216.    for (i=0; i<8; i++) msbin[i] = 0;
  217.  
  218.    /* If all are zero in src8, the msbin should be zero */
  219.    for (i=0; i<8; i++) any_on |= ieee[i];
  220.    if (!any_on) return 0;
  221.  
  222.    sign = ieee[7] & 0x80;
  223.    msbin[6] |= sign;
  224.    msbin_exp = (unsigned)(ieee[7] & 0x7f) * 0x10;
  225.    msbin_exp += ieee[6] >> 4;
  226.  
  227.    if (msbin_exp-0x3ff > 0x80) return 1;
  228.  
  229.    msbin[7] = msbin_exp - 0x3ff + 0x80 + 1; 
  230.  
  231.    /* The ieee mantissa must be shifted up 3 bits */
  232.    ieee[6] &= 0x0f; /* mask out the exponent in the second byte    */
  233.    for (i=6; i>0; i--)
  234.        {
  235.        msbin[i] |= ieee[i] << 3;
  236.        msbin[i] |= ieee[i-1] >> 5;
  237.        }
  238.  
  239.    msbin[0] |= ieee[0] << 3;
  240.  
  241.    return 0;
  242.    }
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.